package com.sleep.drug_traceability.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sleep.drug_traceability.dao.mapper.*;
import com.sleep.drug_traceability.dao.pojo.*;
import com.sleep.drug_traceability.service.InfoService;
import com.sleep.drug_traceability.service.LoginService;
import com.sleep.drug_traceability.service.PerfectService;
import com.sleep.drug_traceability.service.UserService;
import com.sleep.drug_traceability.vo.*;
import com.sleep.drug_traceability.vo.params.OneParam;
import com.sleep.drug_traceability.vo.params.PwdParam;
import com.sleep.drug_traceability.vo.params.SelectParam;
import com.sleep.drug_traceability.vo.params.TwoParam;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

import static com.sleep.drug_traceability.service.impl.LoginServiceImpl.SALT;

/**
 * @author Sleep-6000
 * @date 2022/4/27
 */
@Service
@Transactional
public class InfoServiceImpl implements InfoService {

    @Autowired
    private LoginService loginService;
    @Autowired
    private UserService userService;
    @Autowired
    private PerfectService perfectService;
    @Autowired
    private PerfectManMapper manMapper;
    @Autowired
    private PerfectSelMapper selMapper;
    @Autowired
    private PerfectSupMapper supMapper;
    @Autowired
    private DrugManMapper drugManMapper;
    @Autowired
    private DrugTraMapper drugTraMapper;
    @Autowired
    private DrugSelMapper drugSelMapper;

    @Override
    public Result getManInfo(String token) {
        User user = loginService.checkToken(token);
        if (user == null) {
            return Result.fail(ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TOKEN_ERROR.getMsg());
        }
        ManInfoVo vo = new ManInfoVo();
        vo.setUsername(user.getUsername());
        if (user.getPhoneNumber() == null) {
            vo.setPhoneNumber("18863557896");
        } else {
            vo.setPhoneNumber(user.getPhoneNumber());
        }

        LambdaQueryWrapper<ManInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ManInfo::getUserId, user.getId());
        wrapper.last(" limit 1 ");
        ManInfo manInfo = manMapper.selectOne(wrapper);
        vo.setAddress(manInfo.getAddress());
        vo.setContact(manInfo.getContact());
        vo.setManName(manInfo.getName());
        vo.setLegal(manInfo.getLegal());
        return Result.success(vo);
    }

    @Override
    public Result getSelInfo(String token) {
        User user = loginService.checkToken(token);
        if (user == null) {
            return Result.fail(ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TOKEN_ERROR.getMsg());
        }
        SelInfoVo vo = new SelInfoVo();
        vo.setUsername(user.getUsername());
        if (user.getPhoneNumber() == null) {
            vo.setPhoneNumber("18863557896");
        } else {
            vo.setPhoneNumber(user.getPhoneNumber());
        }

        LambdaQueryWrapper<SelInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SelInfo::getUserId, user.getId());
        wrapper.last(" limit 1 ");
        SelInfo selInfo = selMapper.selectOne(wrapper);
        vo.setSelName(selInfo.getName());
        vo.setAddress(selInfo.getAddress());
        vo.setLegal(selInfo.getLegal());
        vo.setIdNumber(selInfo.getIdNumber());
        return Result.success(vo);
    }

    @Override
    public Result getSupInfo(String token) {
        User user = loginService.checkToken(token);
        if (user == null) {
            return Result.fail(ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TOKEN_ERROR.getMsg());
        }
        SupInfoVo vo = new SupInfoVo();
        vo.setUsername(user.getUsername());
        if (user.getPhoneNumber() == null) {
            vo.setPhoneNumber("18863557896");
        } else {
            vo.setPhoneNumber(user.getPhoneNumber());
        }
        LambdaQueryWrapper<SupInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SupInfo::getUserId, user.getId());
        wrapper.last(" limit 1 ");
        SupInfo supInfo = supMapper.selectOne(wrapper);
        vo.setSupName(supInfo.getName());
        vo.setAddress(supInfo.getAddress());
        vo.setManager(supInfo.getManager());
        return Result.success(vo);
    }

    @Override
    public ManInfo getManInfoByUserId(Long id) {
        LambdaQueryWrapper<ManInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ManInfo::getUserId, id);
        wrapper.last(" limit 1 ");
        return manMapper.selectOne(wrapper);
    }

    @Override
    public SelInfo getSelInfoByUserId(Long id) {
        LambdaQueryWrapper<SelInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SelInfo::getUserId, id);
        wrapper.last(" limit 1 ");
        return selMapper.selectOne(wrapper);
    }

    @Override
    public Result getDrugName(String token) {
        User user = loginService.checkToken(token);
        if (user == null) {
            return Result.fail(ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TOKEN_ERROR.getMsg());
        }
        ManInfo manInfo = getManInfoByUserId(user.getId());
        String manName = manInfo.getName();
        LambdaQueryWrapper<DrugMan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DrugMan::getManName, manName);
        List<DrugMan> drugManList = drugManMapper.selectList(wrapper);
        if (drugManList.size() == 0) {
            return Result.success(null);
        }

        List<String> drugNames = new ArrayList<>();
        for (DrugMan drugMan : drugManList) {
            drugNames.add(drugMan.getName());
        }

        List<String> buyers = perfectService.getAllSellerName();
        DrugNameVo drugNameVo = new DrugNameVo();
        drugNameVo.setDrugNames(drugNames);
        drugNameVo.setManName(manName);
        drugNameVo.setCount(drugNames.size());
        drugNameVo.setBuyers(buyers);

        return Result.success(drugNameVo);
    }

    @Override
    public Result getBatchNum(OneParam param) {
        String drugName = param.getParam();
        if (StringUtils.isBlank(drugName)) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMsg());
        }
        LambdaQueryWrapper<DrugMan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DrugMan::getName, drugName);
        List<DrugMan> drugManList = drugManMapper.selectList(wrapper);
        List<String> list = new ArrayList<>();
        for (DrugMan drugMan : drugManList) {
            list.add(drugMan.getBatchNum());
        }
        return Result.success(list);
    }

    @Override
    public Result getCode(TwoParam twoParam) {
        String drugName = twoParam.getFirst();
        String batchNum = twoParam.getSecond();
        if (StringUtils.isBlank(drugName) || StringUtils.isBlank(batchNum)) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMsg());
        }
        LambdaQueryWrapper<DrugMan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DrugMan::getName, drugName);
        wrapper.eq(DrugMan::getBatchNum, batchNum);
        wrapper.last(" limit 1 ");
        DrugMan drugMan = drugManMapper.selectOne(wrapper);
        return Result.success(drugMan.getTraceableCode());
    }

    @Override
    public Result getDrugTra(String token) {
        User user = loginService.checkToken(token);
        if (user == null) {
            return Result.fail(ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TOKEN_ERROR.getMsg());
        }
        SelInfo selInfo = getSelInfoByUserId(user.getId());
        LambdaQueryWrapper<DrugTra> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DrugTra::getBuyerName, selInfo.getName());
        wrapper.eq(DrugTra::getIsArrive, 0);
        List<DrugTra> drugTraList = drugTraMapper.selectList(wrapper);
        List<String> list = new ArrayList<>();
        for (DrugTra drugTra : drugTraList) {
            list.add(drugTra.getDrugName());
        }
        return Result.success(list);
    }

    @Override
    public Result getManName(OneParam param, String token) {
        String drugName = param.getParam();
        if (StringUtils.isBlank(drugName)) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMsg());
        }
        User user = loginService.checkToken(token);
        if (user == null) {
            return Result.fail(ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TOKEN_ERROR.getMsg());
        }
        String selName = perfectService.getSelName(user.getId());
        LambdaQueryWrapper<DrugTra> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DrugTra::getDrugName, drugName);
        wrapper.eq(DrugTra::getBuyerName, selName);
        wrapper.eq(DrugTra::getIsArrive, 0);
        List<DrugTra> drugTraList = drugTraMapper.selectList(wrapper);
        List<String> list = new ArrayList<>();
        for (DrugTra drugTra : drugTraList) {
            list.add(drugTra.getManName());
        }
        return Result.success(list);
    }

    @Override
    public Result getBatchTra(TwoParam twoParam, String token) {
        String drugName = twoParam.getFirst();
        String manName = twoParam.getSecond();
        if (StringUtils.isBlank(drugName) || StringUtils.isBlank(manName)) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMsg());
        }
        User user = loginService.checkToken(token);
        if (user == null) {
            return Result.fail(ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TOKEN_ERROR.getMsg());
        }
        String selName = perfectService.getSelName(user.getId());
        LambdaQueryWrapper<DrugTra> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DrugTra::getDrugName, drugName);
        wrapper.eq(DrugTra::getManName, manName);
        wrapper.eq(DrugTra::getBuyerName, selName);
        wrapper.eq(DrugTra::getIsArrive, 0);
        List<DrugTra> drugTraList = drugTraMapper.selectList(wrapper);
        List<String> list = new ArrayList<>();
        for (DrugTra drugTra : drugTraList) {
            list.add(drugTra.getBatchNum());
        }
        return Result.success(list);
    }

    @Override
    public Result getCodeTra(SelectParam param, String token) {
        String drugName = param.getDrugName();
        String manName = param.getManName();
        String batchNum = param.getBatchNum();

        if (StringUtils.isBlank(drugName) || StringUtils.isBlank(manName) || StringUtils.isBlank(batchNum)) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMsg());
        }
        User user = loginService.checkToken(token);
        if (user == null) {
            return Result.fail(ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TOKEN_ERROR.getMsg());
        }
        String selName = perfectService.getSelName(user.getId());
        LambdaQueryWrapper<DrugTra> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DrugTra::getDrugName, drugName);
        wrapper.eq(DrugTra::getManName, manName);
        wrapper.eq(DrugTra::getBatchNum, batchNum);
        wrapper.eq(DrugTra::getBuyerName, selName);
        wrapper.eq(DrugTra::getIsArrive, 0);
        DrugTra drugTra = drugTraMapper.selectOne(wrapper);
        return Result.success(drugTra.getTraceableCode());
    }

    @Override
    public Result getDrugCon(String token) {
        User user = loginService.checkToken(token);
        if (user == null) {
            return Result.fail(ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TOKEN_ERROR.getMsg());
        }
        LambdaQueryWrapper<DrugSel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DrugSel::getUserId, user.getId());
        List<DrugSel> drugSelList = drugSelMapper.selectList(wrapper);
        List<String> list = new ArrayList<>();
        for (DrugSel drugSel : drugSelList) {
            list.add(drugSel.getDrugName());
        }
        return Result.success(list);
    }

    @Override
    public Result getBatchCon(OneParam param, String token) {
        String drugName = param.getParam();
        if (StringUtils.isBlank(drugName)) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMsg());
        }
        User user = loginService.checkToken(token);
        if (user == null) {
            return Result.fail(ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TOKEN_ERROR.getMsg());
        }
        String selName = perfectService.getSelName(user.getId());
        LambdaQueryWrapper<DrugSel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DrugSel::getDrugName, drugName);
        wrapper.eq(DrugSel::getSeller, selName);
        List<DrugSel> drugSelList = drugSelMapper.selectList(wrapper);
        List<String> list = new ArrayList<>();
        for (DrugSel drugSel : drugSelList) {
            list.add(drugSel.getBatchNum());
        }
        return Result.success(list);
    }

    @Override
    public Result getCodeCon(TwoParam twoParam, String token) {
        String drugName = twoParam.getFirst();
        String batchNum = twoParam.getSecond();
        if (StringUtils.isBlank(drugName) || StringUtils.isBlank(batchNum)) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMsg());
        }
        User user = loginService.checkToken(token);
        if (user == null) {
            return Result.fail(ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TOKEN_ERROR.getMsg());
        }
        String selName = perfectService.getSelName(user.getId());
        LambdaQueryWrapper<DrugSel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DrugSel::getDrugName, drugName);
        wrapper.eq(DrugSel::getBatchNum, batchNum);
        wrapper.eq(DrugSel::getSeller, selName);
        wrapper.last("limit 1");
        DrugSel drugSel = drugSelMapper.selectOne(wrapper);
        return Result.success(drugSel.getTraceableCode());
    }

    @Override
    public Result changePwd(PwdParam pwdParam, String token) {
        String oldPwd = pwdParam.getOldPwd();
        String newPwd = pwdParam.getNewPwd();
        if (StringUtils.isBlank(oldPwd) || StringUtils.isBlank(newPwd)) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMsg());
        }
        User user = loginService.checkToken(token);
        if (user == null) {
            return Result.fail(ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TOKEN_ERROR.getMsg());
        }
        String pwd = DigestUtils.md5Hex(oldPwd + SALT);
        if (!pwd.equals(user.getPwd())) {
            return Result.fail(ErrorCode.PWD_ERROR.getCode(), ErrorCode.PWD_ERROR.getMsg());
        }
        userService.changePwd(user.getId(), newPwd);
        return Result.success("change success");
    }

    @Override
    public Result changePho(OneParam oneParam, String token) {
        String newPhone = oneParam.getParam();
        if (StringUtils.isBlank(newPhone)) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMsg());
        }
        User user = loginService.checkToken(token);
        if (user == null) {
            return Result.fail(ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TOKEN_ERROR.getMsg());
        }
        userService.changePho(user.getId(), newPhone);
        return Result.success("change success");
    }

    @Override
    public Result changeLegal(OneParam param, String token) {
        String newLegal = param.getParam();
        if (StringUtils.isBlank(newLegal)) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMsg());
        }
        User user = loginService.checkToken(token);
        if (user == null) {
            return Result.fail(ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TOKEN_ERROR.getMsg());
        }
        perfectService.changeLegal(user.getId(), newLegal);
        return Result.success("change success");
    }

    @Override
    public Result changeContact(OneParam param, String token) {
        String newContract = param.getParam();
        if (StringUtils.isBlank(newContract)) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMsg());
        }
        User user = loginService.checkToken(token);
        if (user == null) {
            return Result.fail(ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TOKEN_ERROR.getMsg());
        }
        perfectService.changeContact(user.getId(), newContract);
        return Result.success("change success");
    }
}
